/*
 * @Author: zhangxiao
 * @Email: zhangxiao0125@163.com
 * @Date: 2020-05-22 14:13:32
 * @Last Modified by: zhangxiao
 * @Last Modified time: 2020-08-31 10:54:31
 * @Description: 录制视频，回放，返回视频播放路径。
 */

import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_code_framework/model_data/events/base_event.dart';
import 'package:flutter_code_framework/utils/global.dart';
import 'package:flutter_sfsymbols/flutter_sfsymbols.dart';

import 'package:path_provider/path_provider.dart';
import 'package:progress_dialog/progress_dialog.dart';
import 'package:video_compress/video_compress.dart';
import 'package:video_player/video_player.dart';
import 'package:screen/screen.dart';
class VideoCamera extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _VideoCameraState();
  }
}

class _VideoCameraState extends State<VideoCamera> with WidgetsBindingObserver {

  
  CameraController cameraController;
  VideoPlayerController videoController;
  VoidCallback videoPlayerListener;
  String videoPath;           //录制视频存放路径
  bool _startVisibility=true; //开始按钮
  bool _stopVisibility=false; //停止按钮
  bool _timetwinkle=false;    //录制视频红点
  bool _playBackVideo=false;  //视频回放区域
  bool _enableAudio = true;   //是否开启录制声音
  bool _isFrontCamera=false;  //是否前置摄像头
  String _elapsedTime = '';   //显示录制时长
  bool flag=false;
  int _inSeconds=0;
  int _secods=0;
  double slider=0;
  bool _isCameraStopEorr=false;  //停止摄像头时是否触发异常
  IconData _iconData=SFSymbols.play_circle_fill;
  Stopwatch _watch = new Stopwatch();
  String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
  VideoCompress  _flutterVideoCompress=VideoCompress();
  ProgressDialog pr;
  Subscription _subscription;
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _initCamera();
    // _subscription =VideoCompress.compressProgress$.subscribe((progress) {
      //debugPrint('progress: $progress');
  //});
  }


  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
    if(cameraController!=null)
      cameraController.dispose();
    if(videoController!=null)
      videoController.dispose();
    _subscription.unsubscribe();
  }
 
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (cameraController == null || !cameraController.value.isInitialized) {
      return;
    }
    if (state == AppLifecycleState.inactive) {
      cameraController?.dispose();
    } else if (state == AppLifecycleState.resumed) {
      if (cameraController != null) {
        onNewCameraSelected(cameraController.description);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
   return Scaffold(
     body: Column(
      children: <Widget>[
        Expanded(
              child: Stack(
                children: <Widget>[
                //摄像头区域
                _cameraPreviewWidget(),
                //回放区域
                _thumbnailWidget(),
                  //头部导航
                _leftBarWidget(),
                _ringtBarWidget(),
                //开始录制
                _startPlayWidget(),                
                //停止录制
                _stopPlayWidget(),                 
                //录制时闪烁红点 
                _recordingTwinkleWidget(),            
                  //录制显示秒数
                _recordingTimeWidget(),
                  //回放按钮
                _palyBackVideoWidget(),
                //进度条
                _videoSlider()
              ],
            ),
            flex: 1),
      ],
    ),
   );
  }

  // 预览相机显示区域
  Widget _cameraPreviewWidget() {
    if (cameraController == null || !cameraController.value.isInitialized) {
      return const Text(
        '',
        style: TextStyle(
          color: Colors.white,
          fontSize: 24.0,
          fontWeight: FontWeight.w900,
        ),
      );
    } else {
     final size= MediaQuery.of(context).size;
    return ClipRect(
        child: Container(
          child: Transform.scale(
            scale: cameraController.value.aspectRatio / size.aspectRatio,
            child: Center(
              child: AspectRatio(
                aspectRatio: cameraController.value.aspectRatio,
                child: CameraPreview(cameraController),
              ),
            ),
          ),
        ),
      );
    }
  }
  
///////////////////////////////////////////////////////////////////////////////////////////////////
  //底部区域
  Widget _buttomBaseWidget(List<Widget> _widget){
      return Positioned(
              bottom: 0.0,
                child: Container(
                            width:MediaQuery.of(context).size.width,   
                            height: 64.0,
                            color: Color.fromRGBO(216, 216, 216, 0.5),
                              child:Stack(
                                alignment: Alignment.center,
                                children:_widget
                              ))
                
             );
      }
  
  //播放进度条
  Widget _videoSlider(){
   if(_inSeconds!=0 ){
      try {
         return  Positioned(
           bottom: 40,
           left: -24,
           width:MediaQuery.of(context).size.width+46,
                    child: SliderTheme(
                    data: SliderTheme.of(context).copyWith(
                      activeTrackColor: Color.fromRGBO(236, 115, 100, 1), //实际进度的颜色
                      thumbColor:  Color.fromRGBO(236, 115, 100, 1), //滑块中心的颜色
                      inactiveTrackColor: Color.fromRGBO(143, 146, 154, 1), //默认进度条的颜色
                      inactiveTickMarkColor: Colors.blue, //divisions对进度线分割后 断续线中间间隔的颜色
                      overlayColor: Colors.red[200], //滑块边缘颜色
                      thumbShape: RoundSliderThumbShape(
                        enabledThumbRadius:4 ),
                    ),
                    child:new Slider(   
                            value:_secods==0?0: _secods.toDouble(),
                            max:_inSeconds==0?9999: _inSeconds.toDouble(),
                            min: 0.0,
                            activeColor: Colors.blue,
                            onChanged: (double val) {
                               _secods=val.toInt();
                               videoController.seekTo(Duration(seconds: _secods));
                               flag=true;
                                this.setState(() {
                                    this.slider = val;
                                });
                            },
                        ), 
                    ));
                  // new Slider(
                  //           value:this.slider,
                  //           max: 100.0,
                  //           min: 0.0,
                  //           activeColor: Colors.blue,
                  //           onChanged: (double val) {
                  //               this.setState(() {
                  //                   this.slider = val;
                  //               });
                  //           },
                  //       ),
                  // child: LinearProgressIndicator(
                  //   backgroundColor: Colors.transparent,
                  //   value:(1/_inSeconds*_secods)==0?0.2:1/_inSeconds*_secods,
                  //   valueColor:new AlwaysStoppedAnimation<Color>(Colors.red),
                  // )
                 // )
          //);
      } catch (e) {
      }
    }
  
   return Container(height: 1,width: 1);
 }
  //appbar左侧按钮
  Widget _leftBarWidget(){

    
      return Visibility(
          visible:_startVisibility ||_stopVisibility,
          child:Padding(
            padding: Platform.isAndroid?  EdgeInsets.only(top:MediaQuery.of(context).padding.top):EdgeInsets.only(top:0.1),
            child:Container(
              width:MediaQuery.of(context).size.width,
              height: Platform.isAndroid?(MediaQuery.of(context).padding.top<36?36:MediaQuery.of(context).padding.top):(MediaQuery.of(context).padding.top+44),
              color: Color.fromRGBO(216, 216, 216, 0.5),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                      GestureDetector(child:Padding(padding: EdgeInsets.only(left:20),child:Icon(SFSymbols.chevron_left)),
                      onTap:(){
                        Navigator.of(context).pop();
                      })
                  ],
                )
                ),
          ) 
        );
     }
  

 //appbar 右侧按钮
  Widget _ringtBarWidget(){
     return Visibility(
       visible: !_stopVisibility &&!_startVisibility,
        child:Padding(
            padding: Platform.isAndroid?  EdgeInsets.only(top:MediaQuery.of(context).padding.top):EdgeInsets.only(top:0.1),
       child:Container(
          width:MediaQuery.of(context).size.width,
          height: Platform.isAndroid?(MediaQuery.of(context).padding.top<36?36:MediaQuery.of(context).padding.top):(MediaQuery.of(context).padding.top+44),
          color: Color.fromRGBO(216, 216, 216, 0.5),
              child:Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  Padding(padding: EdgeInsets.only(right: 20),
                   child: SizedBox(
                      height:26.0,
                      width: 60.0,
                      child:RaisedButton(
                        shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.all(Radius.circular(6.0))
                               ),
                        color: Color.fromARGB(255, 236,115, 100),
                        child: Text('完 成',style: TextStyle(fontSize:12,color:  Theme.of(context).primaryTextTheme.button.color),),onPressed: () async{
                             pr = ProgressDialog(
                              context,
                              type: ProgressDialogType.Normal,
                              isDismissible: true,
                            );
                        
                            pr.style(
                              message: '视频压缩中...',
                              borderRadius: 10.0,
                              backgroundColor: Colors.white,
                              progressWidget: CircularProgressIndicator(),
                               elevation: 10.0,
                              insetAnimCurve: Curves.easeInOut,
                              progress: 0.0,
                              maxProgress: 100,
                              progressTextStyle: TextStyle(
                                  color: Colors.black, fontSize: 13.0, fontWeight: FontWeight.w400),
                              messageTextStyle: TextStyle(
                                  color: Colors.black, fontSize: 19.0, fontWeight: FontWeight.w600),
                            );

                              pr.show();
                            
                             await runFlutterVideoCompressMethods(File(videoPath)).then((v)=>{
                               pr.hide(),
                                G.eventBus.fire(RecordingVideoPathEvent(v.path)),
                                 cameraController.dispose(),
                                       Navigator.of(context).pop(v.path)
                             });
                        }) ,
                    )
                  )
                ]
              ),
            ) ), 
     );
  }

  //开始录制/前置按钮
  Widget _startPlayWidget(){
   return  Visibility(
      visible: _startVisibility,
      child: _buttomBaseWidget([
      GestureDetector(
            child:Container(
              height: 50,
              width: 50,
              decoration: new BoxDecoration(
                color: Colors.transparent,
                borderRadius: BorderRadius.all(Radius.circular(150.0)),
                border: new Border.all(width: 4, color: Colors.white),
              ),
              child: Container(
                      decoration: new BoxDecoration(
                          color: Colors.red,
                        borderRadius: BorderRadius.all(Radius.circular(150.0)),
                        border: new Border.all(width: 2, color: Color.fromARGB(255, 236,115, 100)),
                      ),child: Text(''),
              )
            ),
            onTap: onResumeButtonPressed,
          ),
         Positioned(
          right: 20.0,
          child:GestureDetector(
            child: Container(
               child: Icon(SFSymbols.camera_rotate),
           ),
           onTap:(){
             !_isFrontCamera?_initCamera(1):_initCamera();
             if(mounted)
                setState(() {
                  _isFrontCamera= !_isFrontCamera;
                });
           },
          )
         )
   ]));
  }
  
   //录制显示秒数
  Widget _recordingTimeWidget(){
    if(_isCameraStopEorr){
      return Container();
    }
   final top2= (MediaQuery.of(context).padding.top)<36?36:MediaQuery.of(context).padding.top;
    return Visibility(
            visible: _stopVisibility?true:(!_stopVisibility &&!_timetwinkle?true:false),
            child:Padding(
              padding: (EdgeInsets.only(top:MediaQuery.of(context).padding.top+top2+5)),
              child: Container(
              margin: EdgeInsets.only(left:MediaQuery.of(context).size.width/2-10),
              child: new Text(_elapsedTime, style: new TextStyle(fontSize: 18.0,decoration: TextDecoration.none,color:Color.fromARGB(255, 126, 126, 126)))),
            )
      );
  }

  //录制闪烁红点 
  Widget _recordingTwinkleWidget(){
   final top2= (MediaQuery.of(context).padding.top)<36?36:MediaQuery.of(context).padding.top;
    return Visibility(
      visible: _timetwinkle,
      child: Padding(
       padding: (EdgeInsets.only(top:MediaQuery.of(context).padding.top+top2+11)),
       child:Container(
            height: 8.0,
            width: 8.0,
            margin: EdgeInsets.only(left:MediaQuery.of(context).size.width/2-24),
            decoration: new BoxDecoration(
                            color: Colors.red,
                            borderRadius: BorderRadius.all(Radius.circular(150.0)),
                            border: new Border.all(width: 4, color: Colors.red),
                )
          )) ,
      );
    }

  //回放,删除按钮
  Widget _palyBackVideoWidget(){
     if(_isCameraStopEorr){
      return Container();
     }
      return  Visibility(
        visible:!_stopVisibility &&!_startVisibility,
          child:_buttomBaseWidget([
             Positioned(
              left: 10.0,
              bottom: 16.0,
              child:IconButton(icon:Icon(SFSymbols.trash_circle_fill,size: 46.0),color:Colors.black,onPressed:onDelVideoFile)
             ),
            GestureDetector(child: Container(
              height: 50,
              width: 50,
              decoration: new BoxDecoration(
                  color: Colors.transparent,
                  borderRadius: BorderRadius.all(Radius.circular(150.0)),
                  border: new Border.all(width: 4, color: Colors.white),
              ),
              child:Stack(
                children: <Widget>[
                  Positioned(
                    bottom: 2.4,
                    child:Icon(_iconData,color:Colors.white,size: 42))    
                ],
               )), onTap:playBackVideoRecording,
              )
     ])
   );
  }
     
  //停止录制按钮
  Widget _stopPlayWidget(){
    if(_isCameraStopEorr){
      return Container();
    }
    return Visibility(
       visible: _stopVisibility,
       child:_buttomBaseWidget([
        GestureDetector(
            child:Container(
              height:50,
              width: 50,
              decoration: new BoxDecoration(
                  color: Colors.transparent,
                  borderRadius: BorderRadius.all(Radius.circular(150.0)),
                  border: new Border.all(width: 4, color: Colors.white),
              ),
              child:Container(
                      decoration: new BoxDecoration(
                          color: Colors.transparent,
                        borderRadius: BorderRadius.all(Radius.circular(150.0)),
                        border: new Border.all(width: 2, color: Colors.transparent),
                      ),child: new Icon(Icons.stop,color:Colors.red,size:30.0,)
              )
            ),
            onTap:(cameraController != null &&
                        cameraController.value.isInitialized &&
                        cameraController.value.isRecordingVideo)
                    ? onStopButtonPressed
                    : null
          )
    ]));
  }
  
 
  //视频回放区域
  Widget _thumbnailWidget() {

    return Positioned(
      left: 0.0,
      child:Visibility(
        visible: _playBackVideo,
        child: SizedBox(
          child: Container(
              child: videoController == null
                  ? new Container()
                  : AspectRatio(
                      aspectRatio: videoController.value.size != null
                          ? videoController.value.aspectRatio
                          : cameraController.value.aspectRatio,
                      child: VideoPlayer(videoController),
                    )),
          height: MediaQuery.of(context).size.height,
        ))
    );
  }

  //设置屏幕常亮
 _initPlatformState() async {
    double brightness = await Screen.brightness;
    if(mounted)
      setState((){
        Screen.setBrightness(brightness);
          Screen.keepOn(true);
      });
  }
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void onNewCameraSelected(CameraDescription cameraDescription) async {
    if (cameraController != null) {
      await cameraController.dispose();
    }
    cameraController = CameraController(
      cameraDescription,
      ResolutionPreset.medium,
      enableAudio: _enableAudio,
    );

    // If the cameraController is updated then update the UI.
    cameraController.addListener(() {
      if (mounted) setState(() {});
      if (cameraController.value.hasError) {
        //showInSnackBar('Camera error ${cameraController.value.errorDescription}');
      }
    });

    try {
      await cameraController.initialize();
    } on CameraException catch (e) {

    }
    if (mounted) {
      setState(() {});
    }
  }
  
  void onVideoRecordButtonPressed() {
    startVideoRecording().then((_) {
      if (mounted) setState(() {});
    });
  }

  Future<String> startVideoRecording() async {
    if (!cameraController.value.isInitialized) {
      return null;
    }
    final Directory extDir = await getApplicationDocumentsDirectory();
    final String dirPath = '${extDir.path}/Movies/flutter_test';
    await Directory(dirPath).create(recursive: true);
    final String filePath = '$dirPath/${timestamp()}.mp4';
    if (cameraController.value.isRecordingVideo) {
      return null;
    }
    try {
     videoPath = filePath;
     await cameraController.startVideoRecording(filePath);
    } on CameraException catch (e) {
        // logError(e.code, e.description);
      return null;
    }
    return filePath;
  }

  Future<void> stopVideoRecording() async {
    if (!cameraController.value.isRecordingVideo) {
     return null;
    }
    try {
      await cameraController.stopVideoRecording();
      _playBackVideo=true;
      if(videoController==null){
        //初始化视频，并暂停
        await _startVideoPlayer();
        await videoController.pause();
      }
    } catch (e) {
      //发生异常，不显示底部操作按钮
        //初始化视频，并暂停
      _isCameraStopEorr=true;
      setState(() {
        
      });
    }
  }
 
  //回放事件
 Future<void> playBackVideoRecording() async {
  _elapsedTime='';
   if(videoController!=null){
     if(!flag){
        _secods=0;
     }
      _inSeconds=videoController.value.duration.inSeconds;    //视频总长度
     if(videoController.value.initialized && !videoController.value.isPlaying){
      //暂停状态，或未开始播放状态时;
       _iconData=SFSymbols.pause_circle_fill;
       _playBackVideo=!videoController.value.isPlaying;
       await videoController.play();
       if(_secods>0){
          videoController.seekTo(Duration(seconds: _secods));
       }
       videoPlayerListener = () {
         videoController.position.then((pos) {
          setState(() {
            _secods = pos.inSeconds.toInt();
          });
        });

       if (_inSeconds==_secods)  {
            if(mounted) 
            setState(() {
               videoController.removeListener(videoPlayerListener);
            });
           videoController.seekTo(new Duration(seconds:0));
           _iconData=SFSymbols.play_circle_fill;
           videoController.pause();
           flag=false;
           if(mounted)setState(() {});
         }
       };
   
       videoController.addListener(videoPlayerListener);
       if(mounted)setState(() {});
     }else{
       _iconData=SFSymbols.play_circle_fill;
       videoController.pause();
       flag=true;
       videoController.removeListener(videoPlayerListener);
       setState(() {
        
       });
     }
   }
 }

 Future<void> _startVideoPlayer() async {
   try {
    videoController=VideoPlayerController.file(File(videoPath));
    videoController.initialize();
    await videoController.setLooping(true);
    await videoController.play();
    setState(() {
      
    });
   } catch (e) {
    // print('异常信息： '+e.toString());
   }
  }

 List<CameraDescription> cameras = [];
 Future<void> initCameras() async {
    try {
      WidgetsFlutterBinding.ensureInitialized();
      cameras = await availableCameras();
    } on CameraException catch (e) {
      // logError(e.code, e.description);
    }
  }


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  //初始化摄像头 _camera=0 默认后置摄像头
  _initCamera([int _camera=0]){
      initCameras().then((a) => {
          cameraController =CameraController(cameras[_camera], ResolutionPreset.high),
              cameraController.initialize().then((_) {
                if (mounted)
                  setState(() {});
          })
        });
      _initPlatformState();
  }

   //视频录制开始计时
  _start(){
    _watch.start();
    Timer.periodic(new Duration(seconds: 1), _updateTime);
  }

  //更新录制秒数
   _updateTime(Timer timer) { 
    if (_watch.isRunning) {
       if(mounted)
          setState(() {
            _timetwinkle=_timetwinkle?false:true;
            _elapsedTime = _transformMilliSeconds(_watch.elapsedMilliseconds);
          });
    }
  }
 
  
 //开始录制视频事件
  void onResumeButtonPressed()  {
    _startVisibility=false;
    _stopVisibility=true;
    cameraController != null && cameraController.value.isInitialized && !cameraController.value.isRecordingVideo? onVideoRecordButtonPressed(): null;
    _start();
     if(mounted)
       setState(() {});
  }
   //删除录制视频文件
  void onDelVideoFile() {
  _inSeconds=0;
  
  try {
     Directory(videoPath).delete(recursive: true).then((FileSystemEntity fileSystemEntity) {
      videoPath='';
      videoController.removeListener(videoPlayerListener);
      videoController=null; 
     
     setState(() {
       
     });
    });
  } catch (e) {
  }
  
   _startVisibility=true; 
   _stopVisibility=false; 
   _timetwinkle=false;    
   _playBackVideo=false;  
 
   _elapsedTime='';
   if(mounted)
     setState(() {});
  }
  
  //停止录制时，
  void onStopButtonPressed() async {
 
  if (!cameraController.value.isRecordingVideo) {
      return null;
  }
  await stopVideoRecording().then((_) {
        _iconData=SFSymbols.play_circle_fill;
          _stopVisibility=false;
        _timetwinkle=false; 
        _watch.reset();
        _watch.stop();
        if (mounted) setState(() {});
      });
   
  }
  
  
  //时间换算
 _transformMilliSeconds(int milliseconds) {
    int hundreds = (milliseconds / 10).truncate();
    int seconds = (hundreds / 100).truncate();
    int minutes = (seconds / 60).truncate();
    String minutesStr = (minutes % 60).toString().padLeft(2, '0');
    String secondsStr = (seconds % 60).toString().padLeft(2, '0');
    return "$minutesStr:$secondsStr";
  }

    runFlutterVideoCompressMethods(File videoFile) async {
     return await VideoCompress.compressVideo(
      videoFile.path,
      quality: VideoQuality.HighestQuality,
      deleteOrigin: true
    );
  }
}


 
